package com.clstu.syn;

public class SellTicket {
    public static void main(String[] args) {
//        new Sell().start();//Thread 实现多线程
//        new Sell().start();
//        new Sell().start();

        //实现Runnable来实现多线程       //不加锁的话
        Sell01 sell01 = new Sell01();//不论如何都会发生多卖票的现象，超卖
        Sell01 sell02 = new Sell01();//不论如何都会发生多卖票的现象，超卖
        Sell01 sell03 = new Sell01();//不论如何都会发生多卖票的现象，超卖

        new Thread(sell01).start();//不同的对象会有不同的锁，这样就不能实现同步，只有都操作同一个对象才能让锁起作用
        new Thread(sell01).start();
        new Thread(sell01).start();

    }
}

class Sell extends Thread{//Tread实现多线程
    public static int num = 100;
    int count = 0;
    @Override
    public void run() {
        while (num>0){
            System.out.println("窗口=="+Thread.currentThread().getName()+"  售出一张票，还剩票数  "+(--num));
            count++;
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("窗口=="+Thread.currentThread().getName()+" 总共售出票数： "+count);
    }
}

class Sell01 implements Runnable{
    public static int num = 100;
    int count = 0;
    Object object =  new Object();
    private boolean loop = true;

    public synchronized static void m1(){}//这个同步锁则是加在这个类上
    public static void m2() {
        synchronized (Sell01.class) {//静态方法中对代码块加锁只能是 (类名.class)
            System.out.println("hi");
        }
    }

    private /*synchronized*/ void m() {//线程同步方法，同一时刻只能有一个线程能够使用这个方法
        //加上synchronized关键字就是一个线程同步方法
                      //还可以锁一个对象，只要使同一个对象这个锁就起作用,不是同一个对象就锁不住
        synchronized (/*this*/ object /*new Object()*/) {//同步锁还可以家在代码块上面，这个锁锁住的使这个对象本身的代码块或者方法，不是针对这个类
            if (num < 0) {
                loop = false;
                System.out.println("票已经卖完了");
                return;
            }
            System.out.println("窗口==" + Thread.currentThread().getName() + "  售出一张票，还剩票数  " + (num--));
            System.out.println(" 总共售出票数： " + count);
            count++;
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public void run() {
        while (loop) {
             m();
        }
    }
}